const db = require('db/record.js');
const common = require('lib/utils/common.js');
const xlsx = require('node-xlsx');
const controllerDictionary = require('controller/dictionary.js');
const dbCar = require('db/car.js');
const dbPlace = require('db/place.js');

/** @name 添加进出记录 **/
exports.add = async ctx => {
	if(ctx.requiredParams(['number', 'status'])) return;
	// TODO: P5
	const { number, userId, status, pay, payType, placeId, startTime, endTime, note } = ctx.request.body;
	const currentTime = common.YD_dateFormat()
	const options = {
		number,
		userId, // TODO: P1
		status: common.YD_isUndefined(status, 0),
		note,
		updateTime: currentTime,
	}
	if (options.status === 1) { // 支付
		options.pay = pay;
		options.payType = common.YD_isUndefined(payType, '');
		options.endTime = endTime;
	} else { // 未支付
		options.startTime = startTime;
		options.orderCode = common.YD_getOrderCode();
	}
	// TODO: options.status === 1, 未入库的车要直接return
	// 车位信息
	const placeInfo = await updatePlace(options);
	if(!placeInfo) return ctx.fail('暂无空闲车位');
	options.placeId = placeInfo.id;
	// 进出记录
	const findResult = await db.yd_find({ number });
	if (findResult.length > 0) {
		if (options.status === 0) {
			await db.yd_add(options);
		} else {
			const findItem = findResult[0];
			await db.yd_update(options, { id: findItem.id });
		}
	} else {
		if (options.status === 1) {
			return ctx.fail('支付状态异常，请联系管理人员');
		}
		await db.yd_add(options);
	}
	// 同步p_car表
	updateCar(options);
	ctx.success('记录添加成功');
};

/** @name 需要同步车辆记录、车辆状态、用户信息、停车次数 **/
async function updateCar(options) {
	const result = await dbCar.yd_find({ number: options.number });
	const currentTime = common.YD_dateFormat()
	if (result.length > 0) {
		const firstItem = result[0];
		if (options.status === 1) { // 已支付
			await dbCar.yd_update({
				count: firstItem.count + 1,
				status: 0
			}, { number: options.number })
		} else { // 未支付
			await dbCar.yd_update({
				status: 1
			}, { number: options.number })
		}
	} else {
		await dbCar.yd_add({
			number: options.number,
			userId: options.userId,
			status: 1,
			count: 0,
			// TODO: P3
			createTime: currentTime,
			updateTime: currentTime,
		});
	}
}

/** @name 需要同步车位信息、并可能随机分配一个车位 **/
async function updatePlace(options) {
	const placeList = await dbPlace.yd_easyList();
	const fixedPlaceResult = placeList.find(place => place.type === 1 && place.number === options.number);
	if (fixedPlaceResult) { // 固定车位
		await dbPlace.yd_update({ idle: options.status === 0 ? 1 : 0 }, { id: fixedPlaceResult.id })
		return fixedPlaceResult;
	} else { // 非固定车位
		let place = null;
		if (options.status === 0) {
			const residuePlace = placeList.filter(place => place.type === 0 && place.idle === 0);
			if(residuePlace.length <= 0) return null; // 没有车位
			const random = Math.floor(Math.random() * residuePlace.length);
			place = residuePlace[random];
			await dbPlace.yd_update({ idle: 1, number: options.number, userId: options.userId }, { id: place.id })
		} else {
			const targetPlace = placeList.find(place => place.number === options.number);
			if(!targetPlace) return null;	// TODO: 已支付, 但没有找到车停的位置，算是一种异常情况, 其实应该要在上面一开始就拦截已经拦截
			place = targetPlace;
			await dbPlace.yd_update({ idle: 0, number: '', userId: '' }, { id: targetPlace.id })
		}
		return place;
	}
}

/** @name 进出记录列表 **/
exports.list = async ctx => {
	const { number, realname, phone, status, orderCode, payType, placeId } = ctx.query;
	const options = {
		...common.YD_getPageDefault(ctx),
		number, realname, phone, status,
		orderCode, payType, placeId
	}
	const totalRes = await db.yd_count(options);
  const total = totalRes[0].count || 0;
  const rows = await db.yd_list(options);
	rows.forEach(item => {
		item.timeCount = item.endTime ? common.YD_timeInterval(item.startTime, item.endTime) : null
	})
	ctx.success({
    total,
    rows
  });
};

/** @name 编辑进出记录 **/
exports.edit = async ctx => {
	if(ctx.requiredParams(['id'])) return;
	const { id, userId, payType, placeId, note } = ctx.request.body;
	const currentTime = common.YD_dateFormat()
	const options = {
		userId,
		payType,
		placeId,
		note,
		updateTime: currentTime,
	}
	await db.yd_update(options, { id });
	ctx.success('进出记录编辑成功');
};

/** @name 导出进出记录 **/
exports.import = async ctx => {
	if(ctx.requiredParams(['ids'])) return;
	const { ids } = ctx.query;

	// excel相关
	const header = ['车牌号码', '用户名称', '联系电话', '支付状态', '订单号', '停车费(元)',
	'停车时长', '支付方式', '停车开始时间', '停车结束时间', '车位编号', '备注'];
	const keys = ['number', 'realname', 'phone', 'payStatus', 'orderCode', 'pay',
	'timeCount', 'payType', 'startTime', 'endTime', 'placeCode', 'node'];

	// 拉取数据库数据
	const payTypeRes = await controllerDictionary.getPayTypeFun()
	const rows = await db.yd_import({ ids: ids })

	// 数据处理
	const body = [];
	let bodyItem = [];
	rows.forEach(item => {
		keys.forEach(key => {
			if (key === 'timeCount') {
				bodyItem.push(item.endTime ? common.YD_timeInterval(item.startTime, item.endTime) : null)
			} else if (key === 'payType') {
				const payTypeItem = payTypeRes.find(pay => pay.value === item.payType)
				bodyItem.push(payTypeItem?.label || null);
			} else {
				bodyItem.push(item[key]);
			}
		})
		body.push(bodyItem);
		bodyItem = [];
	})
	// 完整excel数据
	const data = [header, ...body];
	const buffer = xlsx.build([{name: 'sheet1', data: data}]);
	const filename = encodeURI(`${common.YD_dateFormat('empty')}-车辆进出记录.xlsx`);
	//设置响应头
	ctx.set('Content-Type', 'application/vnd.openxmlformats');
	ctx.set('Content-Disposition', 'attachment; filename=' + filename);
	//返回结果
	ctx.body = buffer;
};




